/*
 * @Author: xiaosihan
 * @Date: 2023-11-30 18:40:16
 * @Last Modified by: xiehangyun
 * @Last Modified time: 2025-04-17 19:04:51
 */

import FabricCanvas from '@/myFabric/FabricCanvas';
import FabricImage from '@/myFabric/FabricImage';
import FabricText from '@/myFabric/FabricText';
import fontManage from '@/myFabric/fontManage';
import { fabric } from 'fabric';
import { TextOptions } from 'fabric/fabric-impl';
import { get, isEmpty, set } from 'lodash';
import { autorun } from 'mobx';
import Mousetrap from 'mousetrap';
import Transition from 'three-base/Transition';
import designTemplateEditorStore from './designTemplateEditorStore';
import utils from '@/utils/utils';
import { RepeatType } from '#/type';
import { generateUUID } from 'three/src/math/MathUtils.js';

// 设计模版编辑器
class DesignTemplateEditor {
  constructor() {
    window.designTemplateEditor = this;

    // 剪贴版的数据
    let clipboards: Array<{ [key: string]: any }> = [];
    // 数据来源的部位
    let JSON = {};

    //复制对象
    Mousetrap.bind('ctrl+c', () => {
      const activeObjs = this.fabricCanvas.getActiveObjects();
      this.fabricCanvas.discardActiveObject();
      clipboards = activeObjs
        .filter((o) => !['name', 'num'].includes(o.name || '')) // 名字号码元素不能复制
        .map((o) =>
          o.toJSON([
            'id',
            'name',
            'repeat',
            'repeatSpaceX',
            'repeatSpaceY',
            'lockMovementX',
            'lockMovementY',
            'lockRotation',
            'lockScalingX',
            'lockScalingY',
            'lockSkewingX',
            'lockSkewingY',
          ]),
        );
    });

    //粘贴对象
    Mousetrap.bind('ctrl+v', () => {
      if (!isEmpty(clipboards)) {
        clipboards.map((clipboard) => {
          var klass = fabric.util.getKlass(clipboard.type, '');
          clipboard.left += 10;
          clipboard.top += 10;
          if (klass) {
            klass.fromObject(clipboard, (obj: FabricImage | FabricText, error: any) => {
              if (!error) {
                obj.id = utils.uuid();
                this.fabricCanvas.add(obj);
                this.fabricCanvas.setActiveObject(obj);
              }
            });
          }
        });
      }
    });

    // 删除选中的对象
    Mousetrap.bind('del', () => this.delActiveObject());

    // 上移微调
    Mousetrap.bind('up', (e) => {
      this.moveActiveObject(0, -1);
    });
    // 上移粗调
    Mousetrap.bind('shift+up', (e) => {
      this.moveActiveObject(0, -5);
    });
    // 下移微调
    Mousetrap.bind('down', (e) => {
      this.moveActiveObject(0, 1);
    });
    // 下移粗调
    Mousetrap.bind('shift+down', (e) => {
      this.moveActiveObject(0, 5);
    });
    // 左移微调
    Mousetrap.bind('left', (e) => {
      this.moveActiveObject(-1, 0);
    });
    // 左移粗调
    Mousetrap.bind('shift+left', (e) => {
      this.moveActiveObject(-5, 0);
    });
    // 右移微调
    Mousetrap.bind('right', (e) => {
      this.moveActiveObject(1, 0);
    });
    // 右移微调
    Mousetrap.bind('shift+right', (e) => {
      this.moveActiveObject(5, 0);
    });
    // 最大化设计
    Mousetrap.bind('alt+r', (e) => {
      this.maxDesign();
    });
    // 铺满设计区
    Mousetrap.bind('alt+t', (e) => {
      this.coverDesigin();
    });
    // 高度最大化
    Mousetrap.bind('alt+e', (e) => {
      this.upDownCover();
    });
    // 宽度最大化
    Mousetrap.bind('alt+w', (e) => {
      this.leftRightCover();
    });
    // 水平翻转
    Mousetrap.bind('alt+,', (e) => {
      this.flipX();
    });
    // 垂直翻转
    Mousetrap.bind('alt+.', (e) => {
      this.flipY();
    });
    // 左转45°
    Mousetrap.bind('alt+f', (e) => {
      this.leftRotation45();
    });
    // 右转45°
    Mousetrap.bind('alt+g', (e) => {
      this.rightRotation45();
    });
    // 快捷设置平铺类型
    Mousetrap.bind('p', (e) => {
      this.shortcutSetRepeatType();
    });
    //放大
    Mousetrap.bind('alt+=', (e) => {
      this.amplify();
    });
    //缩小
    Mousetrap.bind('alt+-', (e) => {
      this.reduce();
    });
    // //上一步
    // Mousetrap.bind('ctrl+z', (e) => {
    //     designDataHistory.undo();
    // });
    // //下一步
    // Mousetrap.bind('ctrl+shift+z', (e) => {
    //     designDataHistory.redo();
    // });
  }

  //div容器元素
  divDom = (() => {
    const divDom = document.createElement('div');
    divDom.style.width = '400px';
    divDom.style.height = '530px';
    return divDom;
  })();

  // 画布
  canvas = (() => {
    const canvas = document.createElement('canvas');
    canvas.width = 400;
    canvas.height = 530;
    this.divDom.append(canvas);
    return canvas;
  })();

  // fabric 编辑器
  fabricCanvas = (() => {
    const fabricCanvas = new FabricCanvas(this.canvas);
    fabricCanvas.selection = true;
    fabricCanvas.skipOffscreen = false;

    // 选中元素时
    fabricCanvas.on('selection:created', (e) => {
      const activeObject = get(e, ['selected', 0]) as FabricImage | FabricText;
      if (activeObject) {
        designTemplateEditorStore.setActiveObjectId(activeObject.id);
        designTemplateEditorStore.setRotation(activeObject.angle || 0);
        designTemplateEditorStore.setLock(!!activeObject.lockMovementX);

        switch (activeObject.type) {
          case 'image':
            designTemplateEditorStore.setRepeat((activeObject as FabricImage).repeat);
            designTemplateEditorStore.setRepeatSpaceX((activeObject as FabricImage).repeatSpaceX);
            designTemplateEditorStore.setRepeatSpaceY((activeObject as FabricImage).repeatSpaceY);
            designTemplateEditorStore.setRepeatSpacelink(
              (activeObject as FabricImage).repeatSpaceX ===
              (activeObject as FabricImage).repeatSpaceY,
            );
            break;

          case 'i-text':
            designTemplateEditorStore.setFontFamily((activeObject as FabricText).fontFamily);
            designTemplateEditorStore.setFontSize((activeObject as FabricText).fontSize || 20);
            break;

          default:
            break;
        }
      }
    });

    // 选中的元素更新
    fabricCanvas.on('selection:updated', (e) => {
      const activeObject = get(e, ['selected', 0]) as FabricImage;
      if (activeObject) {
        designTemplateEditorStore.setActiveObjectId(activeObject.id);
        designTemplateEditorStore.setRotation(activeObject.angle || 0);
        designTemplateEditorStore.setLock(!!activeObject.lockMovementX);
        if (activeObject.type === 'image') {
          designTemplateEditorStore.setRepeat(activeObject.repeat);
          designTemplateEditorStore.setRepeatSpaceX(activeObject.repeatSpaceX);
          designTemplateEditorStore.setRepeatSpaceY(activeObject.repeatSpaceY);
          designTemplateEditorStore.setRepeatSpacelink(
            activeObject.repeatSpaceX === activeObject.repeatSpaceY,
          );
        } else if (activeObject.type === 'i-text') {
          designTemplateEditorStore.setFontSpace((activeObject as any).charSpacing);
        }
      }
    });

    // 丢失选中的元素
    fabricCanvas.on('selection:cleared', (e) => {
      designTemplateEditorStore.setActiveObjectId('');
    });

    // 元素旋转时
    fabricCanvas.on('object:rotating', (e) => {
      const activeObject = get(e, ['target']) as FabricImage;
      if (activeObject) {
        activeObject.angle = Math.floor(activeObject.angle || 0);
        if (activeObject.angle > 180) {
          activeObject.angle = activeObject.angle - 360;
        }
        designTemplateEditorStore.setRotation(activeObject.angle || 0);
      }
    });

    // 文字调整大小时
    fabricCanvas.on('object:scaling', (e) => {
      const activeObject = get(e, ['target']) as FabricText;
      if (activeObject) {
        if (activeObject.type === 'i-text') {
          const fontSize = activeObject.get('fontSize')!;
          const scaleX = activeObject.get('scaleX')!;
          const newFontSize = Math.max(20, fontSize * scaleX);
          activeObject.set({
            scaleX: 1,
            scaleY: 1,
            fontSize: newFontSize,
            dirty: true,
          });
          designTemplateEditorStore.setFontSize(newFontSize);
        } else if (activeObject.type === 'image') {
        }
      }
    });

    return fabricCanvas;
  })();

  //监听字体加载完成事件 并更新字体
  dispose2 = autorun(
    async () => {
      const { loadedFonts } = fontManage.store;
      await new Promise((resolve) => requestAnimationFrame(resolve));
      const objects = this.fabricCanvas.getObjects();
      objects.map((obj) => {
        if (obj.type === 'i-text' && loadedFonts.includes((obj as FabricText).fontFamily!)) {
          obj.dirty = true;
          (obj as FabricText).initDimensions();
        }
      });
      this.fabricCanvas.renderAll();
    },
    { delay: 50 },
  );

  // 设置容器
  setContainer(div: HTMLDivElement | null) {
    if (div) {
      div.style.overflow = 'hidden';
      div.innerHTML = '';
      div.append(this.divDom);
    }
  }

  //添加图片
  async addImg(name = '图片', url: string) {
    name = name.replace(/(\'|\?|\,|\:|\.)/g, ''); // 去除名字中的特殊字符
    if (url) {
      const img = document.createElement('img');
      img.src = utils.ossSuffix(url, 400);
      img.crossOrigin = 'anonymous';
      img.onload = async () => {

        //1.获取当前选中的对象
        // const objs = this.fabricCanvas.getObjects();
        // const positionArr = [205, 210, 215,];
        // let location = 200;
        // if (objs.length) {
        //   objs.map((obj) => {
        //     positionArr.map((lo: number, index) => {
        //       if (obj.left === lo && obj.top === lo) {
        //         location = positionArr[index + 1];
        //       }
        //     });
        //   });
        // }

        const imgInstance = new FabricImage(img, {
          left: 200,
          top: 200,
        });

        const scale = 200 / Math.max(img.naturalWidth, img.naturalHeight);

        imgInstance.set({
          name,
          id: utils.uuid(),
          width: img.naturalWidth,
          height: img.naturalHeight,
          scaleX: scale,
          scaleY: scale,
        });
        this.fabricCanvas.add(imgInstance);
        this.fabricCanvas.setActiveObject(imgInstance);
        this.render();
      };
    }
  }

  //添加文本
  addText(text: string, options?: TextOptions) {
    const fabricText = new FabricText(text, options);

    fabricText.set({
      id: generateUUID(),
      left: 200,
      top: 265,
    });

    this.fabricCanvas.add(fabricText);
  }

  toJSON() {
    const fabricJson = this.fabricCanvas.toJSON([
      'id',
      'name',
      'repeat',
      'repeatSpaceX',
      'repeatSpaceY',
      'lockMovementX',
      'lockMovementY',
      'lockRotation',
      'lockScalingX',
      'lockScalingY',
      'lockSkewingX',
      'lockSkewingY',
    ]);
    // 设置画布的背景
    // set(fabricJson, ['background'], '#ffffff');
    fabricJson.objects.map((o) => {
      if (o.type === 'image') {
        set(o, ['src'], (get(o, ['src']) || '').replace(/^https?:/, ''));
      }
    });

    return fabricJson;
  }

  // 删除当前选中的对象
  delActiveObject() {
    // 获取当前选中的对象数组
    var selectedObjects = this.fabricCanvas.getActiveObjects();
    // 删除选中的多个对象
    selectedObjects.forEach((object) => {
      this.fabricCanvas.remove(object);
    });
    // 清空选中状态
    this.fabricCanvas.discardActiveObject();

    this.fabricCanvas.renderAll();
  }

  //微调选中的对象
  moveActiveObject(left: number, top: number) {
    const activeObj = this.fabricCanvas.getActiveObject();
    if (activeObj) {
      activeObj.set({
        top: (activeObj.top || 0) + top,
        left: (activeObj.left || 0) + left,
      });
      this.render();
    }
  }

  // 动画对象
  transition = (() => {
    const transition = new Transition({ angle: 0, scaleX: 1, scaleY: 1, left: 512, top: 512 });
    transition.setDuration(150);
    transition.onChange(({ angle, left, top, scaleX, scaleY }) => {
      const activeObject = this.fabricCanvas.getActiveObject();
      if (activeObject) {
        if (angle > 180) {
          angle -= 360;
        } else if (angle < -180) {
          angle += 360;
        }

        activeObject.angle = Math.floor(angle);
        designTemplateEditorStore.setRotation(Math.floor(angle));
        activeObject.left = left;
        activeObject.top = top;
        activeObject.scaleX = scaleX;
        activeObject.scaleY = scaleY;
        this.render();
      }
    });
    return transition;
  })();

  // 重置动画对象的参数;
  resetTransition() {
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject) {
      this.transition.reset({
        angle: activeObject.angle || 0,
        left: activeObject.left || 0,
        top: activeObject.top || 0,
        scaleX: activeObject.scaleX || 1,
        scaleY: activeObject.scaleY || 1,
      });
    }
  }

  //  最大化设计
  maxDesign() {
    this.resetTransition();
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject) {
      // 计算缩放值
      const minSide = Math.min(activeObject.width || 10, activeObject.height || 10);
      const scale = 400 / minSide;
      // 设置缩放值
      this.transition.set({ angle: 0, scaleX: scale, scaleY: scale, left: 200, top: 265 });
    }
  }

  //铺满设计
  coverDesigin() {
    this.resetTransition();
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject) {
      // 计算缩放值
      const scaleX = 400 / (activeObject.width || 10);
      const scaleY = 400 / (activeObject.height || 10);
      // 设置缩放值
      this.transition.set({ angle: 0, scaleX, scaleY, left: 200, top: 265 });
    }
  }

  // 上下铺满
  upDownCover() {
    this.resetTransition();
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject) {
      // 计算缩放值
      const scale = 530 / (activeObject.height || 10);
      // 设置缩放值
      this.transition.set({ angle: 0, scaleX: scale, scaleY: scale, left: 200, top: 265 });
    }
  }

  //左右铺满
  leftRightCover() {
    this.resetTransition();
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject) {
      // 计算缩放值
      const scale = 400 / (activeObject.width || 10);
      // 设置缩放值
      this.transition.set({ angle: 0, scaleX: scale, scaleY: scale, left: 200, top: 265 });
    }
  }

  //放大
  amplify() {
    this.resetTransition();
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject) {
      // 设置缩放值
      this.transition.set({
        scaleX: activeObject.scaleX! * 1.1,
        scaleY: activeObject.scaleY! * 1.1,
      });
    }
  }

  // 缩小
  reduce() {
    this.resetTransition();
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject) {
      // 设置缩放值
      this.transition.set({
        scaleX: activeObject.scaleX! * 0.9,
        scaleY: activeObject.scaleY! * 0.9,
      });
    }
  }

  //  左对齐
  leftAlign() {
    this.resetTransition();
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject) {
      const scaleWidth = activeObject.getScaledWidth();
      // 设置缩放值
      this.transition.set({ left: scaleWidth / 2, });
    }
  }

  // 水平对齐
  horizontalAlign() {
    this.resetTransition();
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject) {
      const canvasWidth = this.fabricCanvas.getWidth();
      // 设置缩放值
      this.transition.set({ left: canvasWidth / 2 });
    }
  }

  // 右对齐
  rightAlign() {
    this.resetTransition();
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject) {
      const scaleWidth = activeObject.getScaledWidth();
      const canvasWidth = this.fabricCanvas.getWidth();
      // 设置缩放值
      this.transition.set({ left: canvasWidth - scaleWidth / 2 });
    }
  }

  // 顶对齐
  topAlign() {
    this.resetTransition();
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject) {
      const scaleHeight = activeObject.getScaledHeight();
      this.transition.set({ top: scaleHeight / 2, });
    }
  }

  // 垂直对齐
  verticalAlign() {
    this.resetTransition();
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject) {
      const canvasHeight = this.fabricCanvas.getHeight();
      this.transition.set({ top: canvasHeight / 2 });
    }
  }

  // 下对齐
  bottomAlign() {
    this.resetTransition();
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject) {
      const scaleHeight = activeObject.getScaledHeight();
      const canvasHeight = this.fabricCanvas.getHeight();
      this.transition.set({ top: canvasHeight - scaleHeight / 2 });
    }
  }



  // 复制
  copy() {
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject) {
      activeObject.clone(
        (newObj: fabric.Object) => {
          newObj.left! += 20;
          newObj.top! += 20;
          this.fabricCanvas.add(newObj);
          this.fabricCanvas.setActiveObject(newObj);
        },
        [
          'id',
          'name',
          'repeat',
          'repeatSpaceX',
          'repeatSpaceY',
          'lockMovementX',
          'lockMovementY',
          'lockRotation',
          'lockScalingX',
          'lockScalingY',
          'lockSkewingX',
          'lockSkewingY',
        ],
      );
    }
  }

  //左右翻转
  flipX() {
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject) {
      activeObject.flipX = !activeObject.flipX;
      this.render();
    }
  }

  // 上下翻转
  flipY() {
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject) {
      activeObject.flipY = !activeObject.flipY;
      this.render();
    }
  }

  // 左转45°
  leftRotation45() {
    this.resetTransition();
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject) {
      // 设置缩放值
      this.transition.set({ angle: (activeObject.angle || 0) - 45 });
    }
  }

  // 右转45°
  rightRotation45() {
    this.resetTransition();
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject) {
      // 设置缩放值
      this.transition.set({ angle: (activeObject.angle || 0) + 45 });
    }
  }

  // 设置旋转角度
  setRotation(angle: number, duration: number = 300) {
    const activeObject = this.fabricCanvas.getActiveObject();

    if (activeObject) {
      this.transition.reset({
        angle: activeObject.angle || 0,
        left: activeObject.left || 0,
        top: activeObject.top || 0,
        scaleX: activeObject.scaleX || 1,
        scaleY: activeObject.scaleY || 1,
      });

      // 设置缩放值
      this.transition.setDuration(duration).set({ angle });
    }
  }

  // 通过id获取对象
  getObjectById(id: string) {
    const objects = this.fabricCanvas.getObjects();
    const object = objects.find((o) => get(o, ['id']) === id);
    return object;
  }

  //设置锁定状态
  setLockState(lock: boolean) {
    designTemplateEditorStore.setLock(lock);
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject) {
      activeObject.set({
        lockMovementX: lock,
        lockMovementY: lock,
        lockRotation: lock,
        lockScalingX: lock,
        lockScalingY: lock,
        lockSkewingX: lock,
        lockSkewingY: lock,
      });
      this.fabricCanvas.renderAll();
    }
  }

  //获取锁定状态通过状态
  getLock(id: string) {
    const object = this.getObjectById(id);
    if (object) {
      return !!object.lockMovementX;
    }
    return false;
  }

  //设置锁定状态通过状态
  setLockById(id: string, lock: boolean) {
    const object = this.getObjectById(id);
    if (object) {
      // 设置当前选中对象的锁定状态
      if (designTemplateEditorStore.activeObjectId === id) {
        designTemplateEditorStore.setLock(lock);
      }

      object.set({
        lockMovementX: lock,
        lockMovementY: lock,
        lockRotation: lock,
        lockScalingX: lock,
        lockScalingY: lock,
        lockSkewingX: lock,
        lockSkewingY: lock,
      });

      this.render();
    }
  }

  // 获取可见状态
  getVisibleById(id: string) {
    const object = this.getObjectById(id);
    if (object) {
      return object.visible;
    }
    return false;
  }

  //设置可见状态
  setVisibleById(id: string, visible: boolean) {
    const object = this.getObjectById(id);
    if (object) {
      object.visible = visible;
      this.render();
    }
  }

  //快捷设置平铺方式
  shortcutSetRepeatType() {
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject && activeObject.type === 'image') {
      switch ((activeObject as FabricImage).repeat) {
        case 'no_repeat':
          this.setRepeatType('base_repeat');
          break;

        case 'base_repeat':
          this.setRepeatType('mirror_repeat');
          break;

        case 'mirror_repeat':
          this.setRepeatType('horizontal_repeat');
          break;

        case 'horizontal_repeat':
          this.setRepeatType('vertical_repeat');
          break;

        case 'vertical_repeat':
          this.setRepeatType('no_repeat');
          designTemplateEditorStore.setShowRepeatSpaceContorl(false);
          break;

        default:
          break;
      }
    }
  }

  //设置平铺类型
  setRepeatType(repeatType: RepeatType) {
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject && activeObject.type === 'image') {
      if ((activeObject as FabricImage).repeat !== repeatType) {
        (activeObject as FabricImage).repeat = repeatType;
        designTemplateEditorStore.setShowRepeatSpaceContorl(true);
      } else {
        (activeObject as FabricImage).repeat = 'no_repeat';
        designTemplateEditorStore.setShowRepeatSpaceContorl(false);
      }
      designTemplateEditorStore.setRepeat((activeObject as FabricImage).repeat);
      this.render();
    }
  }

  //设置平铺的横向间距
  setRepeatSpaceX(repeatSpaceX: number) {
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject && activeObject.type === 'image') {
      (activeObject as FabricImage).repeatSpaceX = repeatSpaceX;
      designTemplateEditorStore.setRepeatSpaceX(repeatSpaceX);
      this.render();
    }
  }

  //设置纵向平铺的方法
  setRepeatSpaceY(repeatSpaceY: number) {
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject && activeObject.type === 'image') {
      (activeObject as FabricImage).repeatSpaceY = repeatSpaceY;
      designTemplateEditorStore.setRepeatSpaceY(repeatSpaceY);
      this.render();
    }
  }

  // 设置选中对象的颜色
  setActiveFill(fill: string) {
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject) {
      activeObject.set({ fill });
      this.render();
    }
  }

  //设置字体
  setFontFontFamily(fontFamily: string) {
    fontManage.loadFont([fontFamily]);
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject && activeObject.type === 'i-text') {
      (activeObject as FabricText).set({ fontFamily });
      this.render();
    }
  }

  //设置字体大小
  setFontSize(fontSize: number) {
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject && activeObject.type === 'i-text') {
      (activeObject as FabricText).set({ fontSize });
      this.render();
    }
  }

  //设置字体间距
  setFontSpace(space: number) {
    const activeObject = this.fabricCanvas.getActiveObject();
    if (activeObject && activeObject.type === 'i-text') {
      (activeObject as FabricText).set({ charSpacing: space });
      this.render();
    }
  }

  // 渲染画布
  async render() {
    this.fabricCanvas.requestRenderAll();
  }
}

const designTemplateEditor = new DesignTemplateEditor();

export default designTemplateEditor;
